package com.jt.aop;

import com.jt.annotation.CacheFind;
import com.jt.utils.ObjectMapperUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.omg.CORBA.ObjectHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.ShardedJedis;

import java.util.Arrays;

@Aspect
@Component
public class CacheAOP {

    @Pointcut("@annotation(com.jt.annotation.CacheFind)")
    public void pointcut(){}

    //    @Around("pointcut()")
//    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
//        Object result = null;
//        Object[] args = joinPoint.getArgs();
//        // 获取注解的prekey
//        CacheFind declaredAnnotation = null;
//        if (joinPoint.getTarget().getClass().isAnnotationPresent(CacheFind.class)) {
//            String preKey = joinPoint.getTarget().getClass().getDeclaredAnnotation(CacheFind.class).preKey();
//            String key = preKey + Arrays.toString(args);
//            if (jedis.exists(key)) {
//                return jedis.get(key);
//            } else {
//                result = joinPoint.proceed();
//                String value = ObjectMapperUtil.toJson(result);
//                jedis.set(key, value);
//                return result;
//            }
//        }
//        return result;
//    }
    // redis 切片机制
//    @Autowired(required = false)
//    private ShardedJedis jedis;
//    @Around("@annotation(cacheFind)")
//    public Object around(ProceedingJoinPoint joinPoint, CacheFind cacheFind) throws Throwable {
//        Object result = null;
//        String preKey = cacheFind.preKey();
//        String key = preKey + "::" + Arrays.toString(joinPoint.getArgs());
//        if (jedis.exists(key)) {
//            String json = jedis.get(key);
//            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
//
//            result = ObjectMapperUtil.toObject(json, methodSignature.getReturnType());
//        } else {
//            result =joinPoint.proceed();
//            String json = ObjectMapperUtil.toJson(result);
//            if (cacheFind.seconds() > 0) {
//                jedis.setex(key, cacheFind.seconds(), json);
//            } else {
//                jedis.set(key, json);
//            }
//        }
//        return result;
//    }
    // redis哨兵机制
//    @Autowired
//    private JedisSentinelPool jedisSentinelPool;
//    @Around("@annotation(cacheFind)")
//    public Object around(ProceedingJoinPoint joinPoint, CacheFind cacheFind) {
//        Jedis jedis = jedisSentinelPool.getResource();
//        Object result = null;
//        try {
//            //1.拼接redis存储数据的key
//            Object[] args = joinPoint.getArgs();
//            String key = cacheFind.preKey() +"::" + Arrays.toString(args);
//
//            //2. 查询redis 之后判断是否有数据
//            if(jedis.exists(key)){
//                //redis中有记录,无需执行目标方法
//                String json = jedis.get(key);
//                //动态获取方法的返回值类型   向上造型  向下造型
//                MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
//                Class returnType = methodSignature.getReturnType();
//                result = ObjectMapperUtil.toObject(json,returnType);
//            }else{
//                //表示数据不存在,需要查询数据库
//                result = joinPoint.proceed();  //执行目标方法及通知
//                //将查询的结果保存到redis中去
//                String json = ObjectMapperUtil.toJson(result);
//                //判断数据是否需要超时时间
//                if(cacheFind.seconds()>0){
//                    jedis.setex(key,cacheFind.seconds(),json);
//                }else {
//                    jedis.set(key, json);
//                }
//            }
//
//        } catch (Throwable throwable) {
//            throwable.printStackTrace();
//        }
//        jedis.close();  //将使用完成的链接记得关闭.
//        return result;
//    }
    // redis集群
    @Autowired
    private JedisCluster jedis;

    @Around("@annotation(cacheFind)")
    public Object around(ProceedingJoinPoint joinPoint, CacheFind cacheFind) throws Throwable {
        Object result = null;
        String preKey = cacheFind.preKey();
        String key = preKey + "::" + Arrays.toString(joinPoint.getArgs());
        if (jedis.exists(key)) {
            String json = jedis.get(key);
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

            result = ObjectMapperUtil.toObject(json, methodSignature.getReturnType());
        } else {
            result =joinPoint.proceed();
            String json = ObjectMapperUtil.toJson(result);
            if (cacheFind.seconds() > 0) {
                jedis.setex(key, cacheFind.seconds(), json);
            } else {
                jedis.set(key, json);
            }
        }
        return result;
    }


}
